﻿using System;
using System.Windows;
using System.Windows.Controls;
using Red.Controls.Shell;
using Red.Core.Extensions;
using Red.EngineData.View;

namespace Red.Controls.ViewModels
{
    /// <summary>
    /// Selectable animation entry in animation set.
    /// </summary>
    public class AnimationSetEntryListItem : TreeItemEngine
    {
        private static Canvas _icon = RedApplication.FindCanvasResource( "appbar_man_walk" );
        private string _animationName;

        /// <summary>
        /// Constructs.
        /// </summary>
        public AnimationSetEntryListItem( TreeItemEngine parent, DataView view, string title, Action<TreeItemEngine> onSynchronized )
            : base( parent, title, null, view, _icon, onSynchronized, String.Empty, false )
        {
            View.Execute( Interop.Make( ".name" ), result => { _animationName = result.Data; Title = _animationName; }, ex => HandleError( "invalid" ) );
        }

        /// <summary>
        /// Select given animation entry.
        /// </summary>
        public void Select()
        {
            Execute( "select" );
        }

        /// <summary>
        /// For drag-n-drop.
        /// </summary>
        public override IDataObject GetDraggedData()
        {
            return new DataObject( "AnimationName", _animationName );
        }

        /// <summary>
        /// Show error in UI.
        /// </summary>
        private void HandleError( string errorMessage )
        {
            Title = errorMessage;
        }
    }

    /// <summary>
    /// Animation set. Animation selector can show many animation sets, we need to group animations by sets.
    /// </summary>
    public class AnimationSetListItem : TreeItemEngine
    {
        private static Canvas _icon = RedApplication.FindCanvasResource( "appbar_people_profile" );

        /// <summary>
        /// Constructs.
        /// </summary>
        public AnimationSetListItem( TreeItemEngine parent, DataView view, string title, Action<TreeItemEngine> onSynchronized )
            : base( parent, title, null, view, _icon, onSynchronized, "entries" )
        {
            View.Execute( Interop.Make( ".name" ), result => Title = result.Data, ex => HandleError( "invalid" ) );
        }

        protected override RedTreeItem CreateTreeItem( DataView childView )
        {
            return new AnimationSetEntryListItem( this, childView, "loading...", null );
        }

        /// <summary>
        /// Show error in UI.
        /// </summary>
        private void HandleError( string errorMessage )
        {
            Title = errorMessage;
        }

        /// <summary>
        /// Select given animation set.
        /// </summary>
        public void Select()
        {
            Execute( "select" );
        }
    }

    /// <summary>
    /// Selectable animation list for multiple animation sets.
    /// Root element of animation selector - a list of animation sets.
    /// </summary>
    public class AnimationSetListRoot : TreeItemEngine
    {
        /// <summary>
        /// We need to refresh view when C++ side decides to add/remove animation set from selector control.
        /// </summary>
        private Notifier _onListChanged;

        /// <summary>
        /// Constructs.
        /// </summary>
        public AnimationSetListRoot( DataView view, Action<TreeItemEngine> onSynchronized )
            : base( null, "Sets", null, view, null, onSynchronized, "list" )
        {
            View.RequestNotifier( "_onListChanged", notifier =>
            {
                _onListChanged = notifier;
                _onListChanged.OnNotifyEvent += async args =>
                    {
                        await RebuildAsync();
                    };
            } );
        }

        protected override RedTreeItem CreateTreeItem( DataView childView )
        {
            return new AnimationSetListItem( this, childView, "loading...", null );
        }
    }
}
